﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using Aleator.Resources;

namespace Aleator.Core
{
    /// <summary>
    /// Abstraction of progression class
    /// </summary>
    abstract public class Progression
    {
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("Degree")]
        abstract public ProgressionDegree[] Degree { get; set; }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        abstract public byte CompositionID { get; set;}

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        abstract public byte ProgressionID { get; set; }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        abstract public byte Numerator { get; set; }

        /// <remarks/>
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        abstract public bool NumeratorSpecified { get; set; }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        abstract public bool Crash { get; set; }

        /// <remarks/>
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        abstract public bool CrashSpecified { get; set; }

        #region Methods

        /// <summary>
        /// Load all of the melodies associated with this progression
        /// </summary>
        abstract public void LoadMelodies();
        
        /// <summary>
        /// Load note clusters for the current melody
        /// </summary>
        /// <param name="m"></param>
        abstract protected void LoadClusters(Melody m);

        #endregion

        #region Properties

        /// <summary>
        /// Owning compisition of this progression
        /// </summary>
        abstract public Composition Composition { get; set; }

        /// <summary>
        /// Chord dictionary for the progression - key is the chord, value is the beat on which the chord starts
        /// </summary>
        abstract public Dictionary<int, Chord> Chords { get; }

        /// <summary>
        /// Hyphen delimted scale degree list for display on the UI.
        /// </summary>
        abstract public string ScaleDegrees { get; set; }

        /// <summary>
        /// This progressions accompanying drum phrase
        /// </summary>
        abstract public DrumPhrase DrumPhrase { get; set; }

        /// <summary>
        /// This progression's bass phrase
        /// </summary>
        abstract public BassPhrase BassPhrase { get; set; }

        /// <summary>
        /// This progression's rhythm (chord playing) phrase
        /// </summary>
        abstract public RhythmPhrase RhythmPhrase { get; set; }

        /// <summary>
        /// This progression's melody phrase
        /// </summary>
        abstract public MelodyPhrase MelodyPhrase { get; set; }

        /// <summary>
        /// Amount of times the progression is repeated
        /// </summary>
        abstract public int Multiplier { get; set; }

        /// <summary>
        /// Total beat length for the progression
        /// </summary>
        abstract public int TotalBeats { get; set; }

        /// <summary>
        /// The number of measures this progression lasts for
        /// </summary>
        abstract public int TotalMeasures { get; }

        /// <summary>
        /// Convenience property to hold all of the notes for this progression
        /// </summary>
        abstract public List<ConcreteNote> Notes { get; set; }

        /// <summary>
        /// Melodies associated with this progression
        /// </summary>
        abstract public List<Melody> Melodies { get; set; }

        /// <summary>
        /// The current measure of the current progression
        /// </summary>
        abstract public int CurrentMeasure { get; set; }

        /// <summary>
        /// Number of beats per repeitition
        /// </summary>
        abstract public int BeatsPerCycle { get; set; }

        /// <summary>
        /// Sequnce of this progression
        /// </summary>
        abstract public int SequenceID { get; set; }

        /// <summary>
        /// Key of the current progression
        /// </summary>
        abstract public CircleOfFifths.Key Key { get; set; }

        #endregion
    }
}
